
/*
功能说明, o表示已经确认,z表示未测试,n表示未实现,x表示未通过,w需要实现,但需要等待,s由软件应该自行实现功能
+-------------------            已经实现
|+------------------            iverilog仿真测试通过
||+-----------------            硬件测试
|||+----------------            建议软件实现
||||
ooz                     cmd_en                      发送命令
ooz                     cmd_need_rsp                命令接收应答
ooz                     cmd_long_rsp                136位命令应答
sss                     cmd_app_cmd                 APP命令模式
sss*                    cmd_sdc_rst (*)             复位,应该发送初始化的命令
sss                     cmd_int_stop                中断停止?
nnn                     *rsp_cmd                    回复的CMD命令,可以不实现
nnn                     *rsp_cmd_app                不实现
wwws                    dcr_blk_size                块大小,ffs计算
nnn                     dcr_dma_en                  DMA开启,可以不实现
ooz                     dcr_data_write              1:数据写入,0:数据读取
ooz                     dcr_data_en                 数据交互开启,(读或写)
ozz                     dtr                         超时,数据时间寄存器.
ozz                     status_rsp_crc_fail         rsp效验错误
ozz                     status_data_crc_fail        数据效验错误
ozz                     status_rsp_crc_ok           rsp效验正确
ozz                     status_data_crc_ok          dat效验正确
ozz                     status_rsp_timeout          rsp超时
ozz                     status_data_timeout         dat超时
ooz                     status_cmd_send             命令发送成功,获得rsp,由idle->busy->idle时,并且timeout为空
ooz                     status_data_end             数据结束,在处理完crc16后设置为1
ooz                     status_fifo_urun            需要,判断发送fifo是否可用
ooz                     status_fifo_orun            需要,判断接收fifo是否可用
nnn                     status_card_change          不需要
wwws                    status_card_detect          需要,应该初始化完成后,存在设备时,应该设置为1
www                     status_write_prot           需要,暂时返回1,无保护
nnn                     int_mask                    因为中断没有实现,所以中断mask不需要
nnn                     pcr_power                   不实现
nnn                     pcr_power_on                不实现
www                     ccr_clk_div(x)		        分频,需要实现,可以暂时不实现
www                     ccr_clk_sd			        0:mmc,1:sd,会判断是否为sd卡
nnn                     ccr_clk_dis			        禁用clk,不实现
www                     ccr_clk_hispd		        高速模式,可以暂时不实现
nnn                     bwr_mode_1bit               1位模式,模式切换不实现,默认使用4bit模式
nnn                     bwr_mode_8bit               8位模式
nnn                     bwr_mode_4bit               4位模式
nnn                     bwr_caps_1bit               模式是否可支持
nnn                     bwr_caps_4bit               模式是否可支持
nnn                     bwr_caps_8bit               模式是否可支持
nnn                     bwr_caps_mask


## (1<<6) 需要RSP
## (1<<7) 136位RSP
## (1<<8) 无作用,APP_CMD
## (1<<9) 开启命令
## (1<<10) 初始化命令
# 设置cmd长度
set *(void**)0xf8000008=48
# 设置rsp长度
set *(void**)0xf800000c=48

#4:argu
#CMD0
set *(void**)0xf800001c=0
set *(void**)0xf8000004=0
set *(void**)0xf800000c=48
set *(void**)0xf8000000=(0<<0)|(1<<9)|(1<<10)

#CMD8
set *(void**)0xf8000004=0x1aa
set *(void**)0xf8000000=(8<<0)|(1<<9)|(1<<6)

print *(void**)0xf8000008
print *(void**)0xf800000c

#CMD55,ACMD41
set *(void**)0xf8000004=0
set *(void**)0xf8000000=(55<<0)|(1<<9)|(1<<6)
set *(void**)0xf8000004=0x40ff8000
set *(void**)0xf8000000=(41<<0)|(1<<9)|(1<<6)
print *(void**)0xf8000008
print *(void**)0xf800000c

#CMD2 (136)
set *(void**)0xf800000c=136
set *(void**)0xf8000000=(2<<0)|(1<<9)|(1<<6)|(1<<7)

#CMD3
set *(void**)0xf800000c=48
set *(void**)0xf8000000=(3<<0)|(1<<9)|(1<<6)
#RCA = rsp[39:24]
#RCA = (rsp0>>24) + ((rsp1 & 0xff)<<8)
print *(void**)0xf8000008
print *(void**)0xf800000c

#CMD7 (设置自RCA)
set *(void**)0xf8000004=0xb368<<16
set *(void**)0xf8000000=(7<<0)|(1<<9)|(1<<6)


#切换4线,ACMD6
set *(void**)0xf8000004=0
set *(void**)0xf8000000=(55<<0)|(1<<9)|(1<<6)
set *(void**)0xf8000004=2
set *(void**)0xf8000000=(6<<0)|(1<<9)|(1<<6)
print *(void**)0xf8000008
print *(void**)0xf800000c

#读取数据,CMD17
# (1<<6) 开启数据传输
# (1<<4) 数据写操作
set *(void**)0xf800001c=(1<<6)
set *(void**)0xf8000004=10
set *(void**)0xf8000000=(17<<0)|(1<<9)|(1<<6)
print *(void**)0xf8000008
print *(void**)0xf800000c

#写数据,CMD24
set *(void**)0xf800001c=(1<<6)|(1<<4)
set *(void**)0xf8000004=10
set *(void**)0xf8000000=(24<<0)|(1<<9)|(1<<6)

#停止读取,CMD12
set *(void**)0xf8000004=0
set *(void**)0xf8000000=(12<<0)|(1<<9)|(1<<6)


#读写fifo数据
print *(void**)0xf8000040
set *(void**)0xf8000040=0x12345678

#输出status寄存器
print *(void**)0xf8000028

*/

module ftsdc010_mmc_sim (
`ifdef SIM
    sdio_cmd_test,
    sdio_dat_test,
`endif

    fifo_send_wren,
    fifo_send_data,
    fifo_send_data_i,
    fifo_send_rden,
    fifo_send_emty,
    fifo_send_full,
    fifo_send_rst,

    fifo_recv_wren,
    fifo_recv_data_o,
    fifo_recv_data_i,
    fifo_recv_rden,
    fifo_recv_emty,
    fifo_recv_full,
    fifo_recv_rst,

    clk,
    rstn,
    sdio_dat,
    sdio_cmd,
    sdio_clk,
    apb_addr,
    apb_pwdata,
    apb_prdata,
    apb_pwrite,
    apb_ptran,
    apb_pready_o,
    apb_psel
);

    output wire         fifo_send_wren;
    output reg[31+8:0]  fifo_send_data;         //mask + 32'data
    output wire         fifo_send_rst;
    input  wire[31+8:0] fifo_send_data_i;
    output wire         fifo_send_rden;
    input  wire         fifo_send_emty;
    input wire          fifo_send_full;

    output wire         fifo_recv_wren;
    output wire[31:0]   fifo_recv_data_o;
    output wire         fifo_recv_rst;
    input  wire[31:0]   fifo_recv_data_i;
    output wire         fifo_recv_rden;
    input  wire         fifo_recv_emty;
    input  wire         fifo_recv_full;

    reg fifo_recv_rden_trg,fifo_recv_rden_trg_nt;
    assign fifo_recv_rden = fifo_recv_rden_trg ^ fifo_recv_rden_trg_nt;
    reg fifo_send_wren_trg,fifo_send_wren_trg_nt;
    assign fifo_send_wren = fifo_send_wren_trg ^ fifo_send_wren_trg_nt;

    input clk;
    input rstn;
    inout wire [3:0]    sdio_dat;
    inout wire          sdio_cmd;
    output wire         sdio_clk;
    input wire[31:0] apb_addr;
    input wire[31:0] apb_pwdata;
    output reg[31:0] apb_prdata;
    input wire apb_pwrite;
    input wire apb_ptran;
    output wire apb_pready_o;
    input wire apb_psel;
    assign apb_pready_o = 1;            //完全异步


    reg[31:0]   argu        =0;
    //wire        cmd_en;
    wire[255:0] rsp;
    wire        need_rsp    = cmd_reg[6];
    wire        long_rsp    = cmd_reg[7];
    wire        cmd_init    = cmd_reg[10]||(cmd[5:0]==0);
    wire        data_en     = dcr[6];
    wire        data_write  = dcr[4];
    wire        dat_crc_ok;
    wire        rsp_crc_ok;
    wire        busy;
    wire        rsp_crc_fail;
    reg         [15:0] block_size = 512;
    reg         [31:0] data_len = 512;

    reg[31:0]
        cmd_reg,
        dcr,
        dtr,
        ccr
        ;

    reg cmd_en_trg,cmd_en_trg_nt;
    reg cmd_en = 0;
    wire cmd_en_nt = cmd_reg[9] & (cmd_en_trg ^ cmd_en_trg_nt);
    wire [5:0] cmd = cmd_reg[5:0];
    wire timeout_flg;
    wire [31:0] status;
    reg [7:0]   cmd_len = 48;
    reg [7:0]   rsp_len = 50;

    wire [31:0] feature;
    wire [7:0]  fifo_depth = 'h80;          //fifo_depth<<8=512字节

    assign feature[7:0]  = fifo_depth;

    assign status[(0) ]  = status_rsp_crc_fail ;
    assign status[(1) ]  = status_dat_crc_fail ;
    assign status[(2) ]  = status_timeout       ;
    assign status[(3) ]  = status_timeout       ;
    assign status[(4) ]  = status_rsp_crc_ok    ;
    assign status[(5) ]  = status_dat_crc_ok    ;
    assign status[(6) ]  = status_cmd_send      ;       //cmd_send
    assign status[(7) ]  = status_dat_end       ;       //数据en
    assign status[(8) ]  = ~fifo_send_full      ;       //直接连接
    assign status[(9) ]  = ~fifo_recv_emty      ;       //接收,直接连接fifo_recv_emty,不需要一个状态寄存器
    assign status[(10)]  = 1'b0   ;
    assign status[(11)]  = 1'b1   ;
    assign status[(12)]  = 1'b0   ;
    assign status[31]    = busy;
    wire data_done;
    wire cmd_done;
    wire dat_write_ok;
    reg  fifo_rst_trg_nt,fifo_rst_trg;
    wire fifo_rst = fifo_rst_trg_nt^fifo_rst_trg;

`define RISE_SIG(a,b)   \
    (a && (a^b))
    reg data_done_pr,  status_dat_end   ,clr_dat_end_trg,clr_dat_end_trg_nt;
    reg cmd_done_pr,   status_cmd_send  ,clr_cmd_send_trg,clr_cmd_send_trg_nt;
    reg rsp_crc_ok_pr, status_rsp_crc_ok,clr_crc_ok_trg  ,clr_crc_ok_trg_nt;
    reg dat_crc_ok_pr, status_dat_crc_ok,clr_dat_crc_ok  ,clr_dat_crc_ok_nt;
    reg timeout_pr   , status_timeout   ,clr_timeout     ,clr_timeout_nt;
    reg status_rsp_crc_fail,clr_rsp_crc_fail_trg,clr_rsp_crc_fail_trg_nt;
    reg status_dat_crc_fail,clr_dat_crc_fail_trg,clr_dat_crc_fail_trg_nt;
    reg [7:0] idle_cnt;
    reg rsp_crc_fail_pr;

    always @(posedge clk or negedge rstn) begin
        if(!rstn)begin
            status_dat_end      <= 0;
            status_cmd_send     <= 0;
            status_rsp_crc_ok   <= 0;
            status_dat_crc_ok   <= 0;
            status_timeout      <= 0;
            status_rsp_crc_fail <= 0;
            status_dat_crc_fail <= 0;
            idle_cnt            <= 0;
            rsp_crc_fail_pr     <= 0;
        end
        else begin
            if(busy)
                idle_cnt    <= 0;
            else if(idle_cnt<'d8)
                idle_cnt <= idle_cnt + 1;

            //状态处理
            //命令完成操作
            cmd_done_pr  <= cmd_done;
            clr_cmd_send_trg <= clr_cmd_send_trg_nt;
            if(clr_cmd_send_trg^clr_cmd_send_trg_nt)
                status_cmd_send <= 0;
            else if(`RISE_SIG(cmd_done,cmd_done_pr))begin
                status_cmd_send <= 1;
            end

            //数据结束处理
            data_done_pr <= data_done;
            clr_dat_end_trg <= clr_dat_end_trg_nt;
            if(clr_dat_end_trg^clr_dat_end_trg_nt)
                status_dat_end <= 0;
            else if(`RISE_SIG(data_done,data_done_pr))
                status_dat_end <= 1;

            //rsp效验码
            rsp_crc_ok_pr   <= rsp_crc_ok;
            clr_crc_ok_trg  <= clr_crc_ok_trg_nt;
            if(clr_crc_ok_trg ^ clr_crc_ok_trg_nt)begin
                status_rsp_crc_ok       <= 0;
            end
            else if(`RISE_SIG(rsp_crc_ok,rsp_crc_ok_pr))        //需要忙碌后进入空闲
                status_rsp_crc_ok <= 1;


            //数据效验码
            dat_crc_ok_pr   <= dat_crc_ok;
            clr_dat_crc_ok  <= clr_dat_crc_ok_nt;
            if(clr_dat_crc_ok^clr_dat_crc_ok_nt)
                status_dat_crc_ok <= 0;
            else if(`RISE_SIG(dat_crc_ok,dat_crc_ok_pr))
                status_dat_crc_ok <= 1;

            //rsp与数据的crc是否失败
            clr_rsp_crc_fail_trg <= clr_rsp_crc_fail_trg_nt;
            clr_dat_crc_fail_trg <= clr_dat_crc_fail_trg_nt;
            rsp_crc_fail_pr      <= rsp_crc_fail;
            //rsp crc失败
            if(clr_rsp_crc_fail_trg ^ clr_rsp_crc_fail_trg_nt)begin
                status_rsp_crc_fail <= 0;
            end
            else if(`RISE_SIG(rsp_crc_fail,rsp_crc_fail_pr))begin
                //crc fail上升
                status_rsp_crc_fail <= 1;
            end

            //dat crc失败
            if(clr_dat_crc_fail_trg ^ clr_dat_crc_fail_trg_nt)
                status_dat_crc_fail <= 0;
            else if(`RISE_SIG(old_busy,busy) && !dat_crc_ok && data_en)begin
                //下降
                status_dat_crc_fail <= 1;
            end

            //超时
            timeout_pr   <= timeout_flg;
            clr_timeout  <= clr_timeout_nt;
            if(clr_timeout^clr_timeout_nt)
                status_timeout <= 0;
            else if(`RISE_SIG(timeout_flg,timeout_pr))
                status_timeout <= 1;
        end
    end

    reg     app_cmd_using;
    reg     app_cmd_using_trg,app_cmd_using_trg_nt;

    sdio_fifo_top u_sdio(
        .clk        (clk            ),
        .rstn       (rstn  ),
        .sdio_dat   (sdio_dat       ),
        .sdio_cmd   (sdio_cmd       ),
        .sdio_clk   (sdio_clk       ),

        .cmd         (app_cmd_using?6'd55:cmd ),
        .argu        (app_cmd_using?32'd0:argu),
        .cmd_en      (cmd_en      ),
        .rsp         (rsp         ),
        .need_rsp    (app_cmd_using?1'b1:need_rsp    ),
        .long_rsp    (app_cmd_using?1'b0:long_rsp    ),
        .data_en     (app_cmd_using?1'b0:data_en    ),
        .data_write  (app_cmd_using?1'b0:data_write ),
        .block_size  (block_size  ),
        .data_len    (data_len    ),
        .data_crc_ok (dat_crc_ok  ),
        .rsp_crc_ok  (rsp_crc_ok  ),
        .rsp_crc_fail(rsp_crc_fail),
        .busy        (busy        ),
        .data_done   (data_done   ),
        .cmd_done    (cmd_done    ),
        .cmd_len     (cmd_len     ),
        .cmd_init    (cmd_init    ),
        .rsp_len     (app_cmd_using?'d48:rsp_len),
        .dat_write_ok   (dat_write_ok),

        .clk_div     (ccr[6:0]),

        .timeout_time(dtr),
        .timeout(timeout_flg),
/*
    fifo_send_wren,
    fifo_send_data,
    fifo_send_data_i,
    fifo_send_rden,
    fifo_send_emty,
    fifo_send_full,
    fifo_send_rst,

    fifo_recv_wren,
    fifo_recv_data_o,
    fifo_recv_data_i,
    fifo_recv_rden,
    fifo_recv_emty,
    fifo_recv_full,
    fifo_recv_rst,
*/
        .fifo_send_emty  (fifo_send_emty  ),
        .fifo_send_data_i(fifo_send_data_i),
        .fifo_send_rden  (fifo_send_rden  ),


        .fifo_recv_data_o (fifo_recv_data_o),
        .fifo_recv_wren   (fifo_recv_wren  ),
        .fifo_recv_full   (fifo_recv_full  ),
        .fifo_send_rst    (io_fifo_send_rst   ),
        .fifo_recv_rst    (io_fifo_recv_rst   )
    );

    wire io_fifo_send_rst,io_fifo_recv_rst;
    assign fifo_send_rst = dcr[10]|io_fifo_send_rst;
    assign fifo_recv_rst = dcr[10]|io_fifo_recv_rst;

    reg  wait_cmd;
    reg  old_busy;

    reg  cmd_data_status_done = 0;

    reg  cmd_rst_trg,cmd_rst_trg_nt;
    wire cmd_rst = cmd_rst_trg^cmd_rst_trg_nt;

    reg  fifo_recv_first_read;
    reg  fifo_recv_first_read_trg,fifo_recv_first_read_trg_nt;

    //APP_CMD
    reg cmd_app_cmd_trg_nt,cmd_app_cmd_trg;

    always @(posedge clk or negedge rstn) begin
        if(!rstn)begin
            argu                    <= 0;
            block_size              <= 512;
            fifo_recv_rden_trg      <= 0;
            fifo_recv_rden_trg_nt   <= 0;
            wait_cmd                <= 0;
            old_busy                <= 0;
            cmd_rst_trg             <= 0;
            cmd_rst_trg_nt          <= 0;
            cmd_len                 <= 48;
            rsp_len                 <= 48;
            dcr                     <= 0;
            dtr                     <= 32'd100_000_000;     //100MHz == 1sec
            fifo_recv_first_read_trg_nt <= 0;
            cmd_app_cmd_trg_nt      <= 0;
            cmd_app_cmd_trg         <= 0;
            fifo_recv_first_read_trg    <= 0;
            fifo_recv_first_read    <= 0;
            app_cmd_using           <= 0;
            ccr                     <= 0;
        end
        else begin
            fifo_rst_trg        <= fifo_rst_trg_nt;
            cmd_en_trg          <= cmd_en_trg_nt;
            old_busy            <= busy;

            //fifo_recv_rden_trg  <= fifo_recv_rden_trg_nt;

            fifo_send_wren_trg      <= fifo_send_wren_trg_nt;
            fifo_recv_first_read_trg <= fifo_recv_first_read_trg_nt;

            if(fifo_recv_first_read_trg ^ fifo_recv_first_read_trg_nt)
                fifo_recv_first_read <= 0;          //重置第一次读取fifo的状态
            else if(~fifo_recv_first_read)begin
                if(!fifo_recv_emty)begin
                    //读取第一个fifo数据
                    fifo_recv_first_read <= 1;
                    fifo_recv_rden_trg <= ~fifo_recv_rden_trg_nt;
                end
            end
            else begin
                //fifo_recv_first_read_trg <= fifo_recv_first_read_trg_nt;
                fifo_recv_rden_trg  <= fifo_recv_rden_trg_nt;
            end

            //APP CMD
            cmd_app_cmd_trg     <= cmd_app_cmd_trg_nt;
            app_cmd_using_trg   <= app_cmd_using_trg_nt;
            if(app_cmd_using_trg_nt^app_cmd_using_trg)begin
                //触发APP读取
                app_cmd_using   <= 1;
                cmd_en          <= 1;
            end
            else begin
                //普通命令或者APP_CMD命令
                if(app_cmd_using&&`RISE_SIG(old_busy,busy))begin
                    //实际上是busy  1->0的状态
                    //结束处理,结束app_cmd_using
                    app_cmd_using <= 0;
                    cmd_en  <= 1;       //结束的时候,执行ACMD指令
                end
                else begin
                    cmd_en  <= cmd_en_nt;
                end
            end

            if(apb_psel && apb_ptran)begin
                if(apb_pwrite)
                    case (apb_addr[5+2:2])
                        'd0:begin
                            cmd_reg         <= apb_pwdata;
                            cmd_rst_trg_nt  <= cmd_rst_trg_nt^apb_pwdata[10];    //cmd_rst



                            if(apb_pwdata[9]&apb_pwdata[8])begin
                                //ACMD命令
                                cmd_app_cmd_trg_nt      <= cmd_app_cmd_trg_nt^(apb_pwdata[9]&apb_pwdata[8]);
                                app_cmd_using_trg_nt    <= ~app_cmd_using_trg_nt;
                                cmd_en_trg_nt           <= cmd_en_trg_nt^apb_pwdata[9];      //cmd_en
                            end
                            else begin
                                //普通CMD
                                cmd_en_trg_nt       <= cmd_en_trg_nt^apb_pwdata[9];      //cmd_en
                                if(apb_pwdata[7])
                                    rsp_len <= 136;
                                else
                                    rsp_len <= 48;
                                if(apb_pwdata[10])begin
                                    dcr <= 0;
                                end
                            end
                        end
                        'd1:argu <= apb_pwdata;
                        'd2:cmd_len <= apb_pwdata[7:0];        //cmd len
                        'd3:rsp_len <= apb_pwdata[7:0];         //rsp len
                        'd3:;        //rsp
                        'd4:;        //rsp
                        'd5:;        //rsp
                        'd6:;        //rsp cmd
                        'd7:begin
                            dcr              <= apb_pwdata;
                            fifo_rst_trg_nt             <= fifo_rst_trg_nt^dcr[10];
                            fifo_recv_first_read_trg_nt <= fifo_recv_first_read_trg_nt^dcr[10];
                            //设置块大小
                            block_size         <= 1<<apb_pwdata[3:0];
                        end
                        'd8:dtr         <= apb_pwdata;
                        'd9:data_len    <= apb_pwdata;
                        'd10:;      //状态
                        'd11: begin
                            //apb_prdata <= 0;       //clr 清除状态寄存器
                            clr_cmd_send_trg_nt     <= clr_cmd_send_trg_nt ^apb_pwdata[6];
                            clr_dat_end_trg_nt      <= clr_dat_end_trg_nt  ^apb_pwdata[7];
                            clr_crc_ok_trg_nt       <= clr_crc_ok_trg_nt   ^(apb_pwdata[4]);
                            clr_dat_crc_ok_nt       <= clr_dat_crc_ok_nt   ^(apb_pwdata[5]);
                            clr_timeout_nt          <= clr_timeout_nt      ^(apb_pwdata[2]|apb_pwdata[3]);
                            clr_dat_crc_fail_trg_nt <= clr_dat_crc_fail_trg_nt ^ apb_pwdata[1];
                            clr_rsp_crc_fail_trg_nt <= clr_rsp_crc_fail_trg_nt ^ apb_pwdata[0];
                        end
                        'd12:;       //int mask 中断位掩码
                        'd13:;       //电源控制
                        'd14:ccr <= apb_pwdata;       //时钟控制
                        'd15:;       //总线位宽设置
                        'd16:begin
                            //数据写入fifo
                            fifo_send_data         <= apb_pwdata;
                            fifo_send_wren_trg_nt  <= ~fifo_send_wren_trg_nt;
                        end
                        default:;
                    endcase
                else
                    case (apb_addr[5+2:2])
                        'd0:apb_prdata  <= cmd_reg;
                        'd1:apb_prdata  <= argu;
                        'd2:apb_prdata  <= rsp[32*1-1+8:32*0+8];
                        'd3:apb_prdata  <= rsp[32*2-1+8:32*1+8];
                        'd4:apb_prdata  <= rsp[32*3-1+8:32*2+8];
                        'd5:apb_prdata  <= rsp[32*4-1+8:32*3+8];
                        'd6:apb_prdata  <= 0;        //rsp cmd
                        'd7:apb_prdata  <= dcr;
                        'd8:apb_prdata  <= dtr;
                        'd9:apb_prdata  <= data_len;
                        'd10:apb_prdata <= status;  //
                        'd11:apb_prdata <= 0;       //clr 清除状态寄存器
                        'd12:apb_prdata <= 0;       //int mask 中断位掩码
                        'd13:apb_prdata <= 0;       //电源控制
                        'd14:apb_prdata <= ccr;       //时钟控制
                        'd15:apb_prdata <= 0;       //总线位宽设置
                        'd16:begin
                            //数据读取,然后从fifo拉取一个数据
                            //
                            apb_prdata                  <=  {fifo_recv_data_i[7:0],fifo_recv_data_i[15:8],fifo_recv_data_i[23:16],fifo_recv_data_i[31:24]};
                            fifo_recv_rden_trg_nt       <=  ~fifo_recv_rden_trg_nt;
                        end
                        'd17:apb_prdata <= feature;         //0x44
                        'd18:apb_prdata <= rsp[31:0];       //包括crc7
                        default:;
                    endcase
            end
        end
    end

endmodule